﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using SpiritEngine;
using SpiritEngine.Components2D;

using SimNations.Pathfinding;


namespace SimNations.City
{
    public class City2D : ACity
    {
        // MEMBER VARIABLES
        // ------------------------------------------------------------------------------------------------------------------------

        Vector2[] route;


        // CONSTRUCTORS
        // ------------------------------------------------------------------------------------------------------------------------

        public City2D()
            : base()
        {

        } // end City2D::City2D()

        public City2D(int Height, int Width)
            : base(Height, Width)
        {

        } // end City2D::City2D(int, int)


        // PRIVATE/PROTECTED METHODS
        // ------------------------------------------------------------------------------------------------------------------------

        protected override void InitCityGrid()
        {
            m_CityGrid = new CityTile2D[m_CityWidth, m_CityHeight];

            for (int x = 0; x < m_CityWidth; x++)
            {
                for (int y = 0; y < m_CityHeight; y++)
                {
                    m_CityGrid[x, y] = new CityTile2D(x, y, this);                   

                } // end for x
            } // end for y

        } // end City2D::InitCityGrid()


        protected override void Load()
        {
            base.Load();


            for (int x = 0; x < m_CityWidth; x++)
            {
                for (int y = 0; y < m_CityHeight; y++)
                {
                    m_CityGrid[x, y].LoadComponent();

                } // end for x
            } // end for y

        } // end City2D::Load()



        // METHODS
        // ------------------------------------------------------------------------------------------------------------------------

        public override void Draw()
        {
            for (int x = 0; x < m_CityWidth; x++)
            {
                for (int y = 0; y < m_CityHeight; y++)
                {
                    m_CityGrid[x, y].Draw();

                } // end for y
            } // end for x

            DrawRoute();

        } // end City2D::Draw()


        // DEBUG METHODS
        // ------------------------------------------------------------------------------------------------------------------------

#if (DEBUG)

        public void DrawRoute()
        {
            Vector2 point1;
            Vector2 point2;
            Vector2 centerPoint = new Vector2(16, 16);

            for (int i = 0; i < route.Length - 1; i++)
            {
                point1 = route[i] * 32;
                point2 = route[i + 1] * 32;


                if (point1.X == point2.X)
                {
                    point1.Y += 16;
                    point2.Y += 16;
                }

                else if (point1.Y == point2.Y)
                {
                    point1.X += 16;
                    point2.X += 16;
                }

                else
                {
                    point1.X += 16;
                    point2.X += 16;
                    point1.Y += 16;
                    point2.Y += 16;
                }


                // Apply offset of the City's current scrolled position
                point1 += this.Position;
                point2 += this.Position;


                if (i == 0)
                    this.Engine.DrawLine(2, Color.Green, point1, point2);
                else if (i == route.Length - 2)
                    this.Engine.DrawLine(2, Color.Red, point1, point2);
                else
                    this.Engine.DrawLine(2, Color.Blue, point1, point2);

            }

        } // end City2D::DrawRoute()


        public void LoadSimpleMap(string fileName)
        {
            int height;
            int width;
            Vector2 startPoint = Vector2.Zero;
            Vector2 endPoint = Vector2.Zero;
            string temp;
            string sub; // stores a substring


            using (StreamReader reader = new StreamReader(fileName))
            {
                // First read in the height and width from the map file
                temp = reader.ReadLine();
                width = Convert.ToInt32(temp);

                temp = reader.ReadLine();
                height = Convert.ToInt32(temp);


                // Read in the start and end points
                temp = reader.ReadLine();
                startPoint.X = Convert.ToInt32(temp);
                temp = reader.ReadLine();
                startPoint.Y = Convert.ToInt32(temp);

                temp = reader.ReadLine();
                endPoint.X = Convert.ToInt32(temp);
                temp = reader.ReadLine();
                endPoint.Y = Convert.ToInt32(temp);


                // Plug the info into the PathFinder
                m_PathFinder.StartingSquare = new Square(startPoint);
                m_PathFinder.EndingSquare = new Square(endPoint);
                m_PathFinder.World = m_CityGrid;



                // Now reinitialize the city grid to the size of this map
                m_CityWidth = width;
                m_CityHeight = height;
                InitCityGrid();


                // Now we need to read in the map data line by line
                for (int y = 0; y < m_CityHeight; y++)
                {
                    temp = reader.ReadLine();

                    for (int x = 0; x < m_CityWidth; x++)
                    {
                        sub = temp.Substring(x * 3, 2);
                        sub.Trim();


                        //Console.WriteLine("X: {0}   Y: {1}  Val: {2}", x, y, sub);

                        m_CityGrid[x, y].ParentCity = this;
                        m_CityGrid[x, y].LoadComponent();

                        switch (sub)
                        {
                            case "00":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.None;
                                } break;

                            case "C1":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.LightCommercial;
                                } break;

                            case "C2":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.MediumCommercial;
                                } break;

                            case "C3":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.HeavyCommercial;
                                } break;

                            case "R1":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.LightResidential;
                                } break;

                            case "R2":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.MediumResidential;
                                } break;

                            case "R3":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.HeavyResidential;
                                } break;

                            case "I1":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.LightIndustrial;
                                } break;

                            case "I2":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.MediumIndustrial;
                                } break;

                            case "I3":
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.HeavyIndustrial;
                                } break;

                            case "R-":
                                {
                                    m_CityGrid[x, y].TransitType = TransitTypes.Road;
                                } break;

                            default:
                                {
                                    m_CityGrid[x, y].ZoneType = Zones.None;
                                } break;

                        } // end switch sub



                    } // end for x

                } // end for y


            } // Using (StreamReader)


            m_PathFinder.AllowOrthogonalMovesOnly = true;
            m_PathFinder.StartingSquare = new Square(this.GetNearestTransitTile(startPoint, TransitTypes.Road));
            m_PathFinder.EndingSquare = new Square(this.GetNearestTransitTile(endPoint, TransitTypes.Road));
            m_PathFinder.World = m_CityGrid;
            
            this.route = m_PathFinder.FindRoute();


        } // end City2D::LoadSimpleMap(string)


#endif



        // PROPERTIES
        // ------------------------------------------------------------------------------------------------------------------------



        // EVENTS
        // ------------------------------------------------------------------------------------------------------------------------


    } // end class City2D
}
